Repository navigation
Receive a wanted title with a clear action, then open its new copy - #49
fabiodalez-dev wants to merge 1 commit into
Conversation
On a wanted title the trailing "Ricevuto" (Received) read as a status, so a title still wanted with no copies looked already received, and one tap added a copy with no question. The button now says "Ricevi" (Receive) and asks before adding the copy. Receiving a wanted title or an offer creates a copy that still needs its code and place. The app now opens the record, scrolls to the copies and opens that copy's editor straight away, through an optional copy argument on the book editor route.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
ℹ️ No critical issues — two rough edges in the new jump-to-copy flow, inline.
Reviewed changes
Reviewed the single commit that turns the wanted-title button into a confirmed action and routes every receipt to the new copy's editor.
- Confirm before receiving a wanted title — the row button now reads as an action (
staff_wanted_mark_receivedrelabelled in all four locales), andaskReceiveWanted/receiveWantedgo through aConfirmDialog. openCopyhand-off — a successful wanted or offer receipt setsDesiderataUiState.openCopy, which the screen consumes and passes to the newonOpenCopycallback.- Optional
copyroute argument —STAFF_BOOK_EDITgains?copy={copyId}(default 0); existingstaffBookEdit(id)callers still resolve to the same destination. - Auto-open in
StaffCopiesSection— once the copy shows up instate.copies, the section scrolls into view and callsstartEdit.StaffBookEditViewModel.openCopyIdis cleared on first use, so recompositions and rotations don't reopen it. - Device tests — cancel sends nothing, confirm sends one request, and all three receipt paths land on
copy-save.
claude-opus-5-5 | 𝕏
| is ApiResult.Success -> it.copy(busy = false, message = StaffMessage(R.string.staff_wanted_received, args = listOf(book.title))) | ||
| is ApiResult.Success -> it.copy( | ||
| busy = false, message = StaffMessage(R.string.staff_wanted_received, args = listOf(book.title)), | ||
| openCopy = res.data.copyId?.takeIf { c -> c > 0 }?.let { c -> res.data.bookId to c }, |
There was a problem hiding this comment.
WantedReceiveResult.bookId defaults to 0. If the server leaves out book_id but sends copy_id, this navigates to staffBookEdit(0, copy), and StaffBookEditViewModel.isEdit (bookId > 0) then opens the new-book form instead of the record. The title being received is already in book.id, so falling back to it removes the risk.
| openCopy = res.data.copyId?.takeIf { c -> c > 0 }?.let { c -> res.data.bookId to c }, | |
| openCopy = res.data.copyId?.takeIf { c -> c > 0 }?.let { c -> (res.data.bookId.takeIf { b -> b > 0 } ?: book.id) to c }, |
| /** The record and copy a received offer produced, when the server names both. */ | ||
| private fun receivedCopy(offer: StaffOffer): Pair<Int, Int>? { | ||
| if (offer.status != "received") return null | ||
| val book = offer.receivedBook?.id ?: offer.book?.id ?: return null |
There was a problem hiding this comment.
Same 0 id problem as the wanted path. IdTitle.id defaults to 0, so a received_book object without an id never falls back to book and sends you to the new-book form. OfferSheet already guards this with (offer.receivedBook ?: offer.book)?.takeIf { it.id > 0 }, and reusing that shape keeps the two consistent.
| val book = offer.receivedBook?.id ?: offer.book?.id ?: return null | |
| val book = offer.receivedBook?.id?.takeIf { it > 0 } ?: offer.book?.id?.takeIf { it > 0 } ?: return null |
| // Arriving from a receipt: scroll to the copies and open the new copy's editor at once. | ||
| val bringIntoView = remember { BringIntoViewRequester() } | ||
| LaunchedEffect(openCopyId, state.copies) { | ||
| val copy = state.copies.firstOrNull { it.id == openCopyId } ?: return@LaunchedEffect |
There was a problem hiding this comment.
The section also renders when only areas.labels is on (line 240), but this effect doesn't check areas.copies. On a server with labels but no per-copy management, the receipt still opens CopyEditorSheet, which is UI the user otherwise can't reach, and saving it calls updateCopy on an area the server doesn't offer. Gating the auto-open on areas.copies keeps the jump consistent with the list.
| val copy = state.copies.firstOrNull { it.id == openCopyId } ?: return@LaunchedEffect | |
| val copy = state.copies.firstOrNull { it.id == openCopyId }?.takeIf { areas.copies } ?: return@LaunchedEffect |

Two changes to the donation offers in the admin area.
The wanted-title button is an action, not a status. In "Titoli cercati" each row had a trailing text button labelled "Ricevuto" (Received). It read as the title's state, so a book still wanted with 0 copies looked already received. One tap also added a copy straight away. The button now says "Ricevi" / "Receive" / "Empfangen" / "Recevoir", and it asks for confirmation before adding the copy.
After a receipt the new copy opens on the record. Receiving a wanted title or an offer creates a copy that still needs its inventory code and place. The app now opens the book record, scrolls to the copies and opens that copy's editor. The book editor route takes an optional
copyargument for this.Tests: DesiderataStaffFlowTest covers the confirm dialog (cancel sends nothing, confirm sends one request) and the jump to the new copy's editor for a wanted title, an offer for a wanted title and an offer received into a picked record. Full suites on the emulator: 93 instrumented and 389 unit tests pass.